import { INode, IModel } from '../store/configdef/types'

function handleModel(modelNode: INode): any {
  const containers: any[] = []
  const model = {
    name: modelNode.data.label,
    isNew: modelNode.data.isNew,
    description: modelNode.data.description,
    lowerMultiplicity: modelNode.data.lowerMultiplicity,
    upperMultiplicity: modelNode.data.upperMultiplicity,
    compileTimeType: modelNode.data.compileTimeType,
    containers: containers
  }

  modelNode.children?.forEach((item) => {
    model.containers.push(handleContainer(item))
  })

  return model
}

function handleContainer(containerNode: INode) {
  const subContainers: any[] = [],
    parameters: any[] = [],
    references: any[] = []
  const container = {
    name: containerNode.data.label,
    isNew: containerNode.data.isNew,
    description: containerNode.data.description,
    lowerMultiplicity: containerNode.data.lowerMultiplicity,
    upperMultiplicity: containerNode.data.upperMultiplicity,
    subContainers,
    parameters,
    references,
    UUID: containerNode.id
  }

  containerNode.children?.forEach((item) => {
    if (item.data.type === 'container' || item.data.type === 'subContainer') {
      container.subContainers.push(handleContainer(item))
    } else if (item.data.type === 'parameter') {
      container.parameters.push(handleParameter(item))
    } else if (item.data.type === 'reference') {
      container.references.push(handleReference(item))
    }
  })
  return container
}

function handleParameter(parameterNode: INode) {
  const literals: any[] = []
  const parameter = {
    name: parameterNode.data.label,
    isNew: parameterNode.data.isNew,
    description: parameterNode.data.description,
    lowerMultiplicity: parameterNode.data.lowerMultiplicity,
    upperMultiplicity: parameterNode.data.upperMultiplicity,
    type: parameterNode.data.parameterType,
    defaultValue: parameterNode.data.defaultValue,
    min: parameterNode.data.min,
    max: parameterNode.data.max,
    literals,
    UUID: parameterNode.id
  }

  parameterNode.children?.forEach((item) => {
    parameter.literals.push(handleLiteral(item))
  })
  return parameter
}

function handleReference(referenceNode: INode) {
  const destinations: any[] = []
  const reference = {
    name: referenceNode.data.label,
    isNew: referenceNode.data.isNew,
    description: referenceNode.data.description,
    lowerMultiplicity: referenceNode.data.lowerMultiplicity,
    upperMultiplicity: referenceNode.data.upperMultiplicity,
    type: referenceNode.data.referenceType,
    scope: referenceNode.data.scope,
    destinations,
    UUID: referenceNode.id
  }

  referenceNode.children?.forEach((item) => {
    reference.destinations.push(handleDestination(item))
  })

  return reference
}

function handleLiteral(literalNode: INode) {
  const literal = {
    name: literalNode.data.label,
    isNew: literalNode.data.isNew,
    UUID: literalNode.id
  }

  return literal
}

function handleDestination(destinationNode: INode) {
  const destination = {
    name: destinationNode.data.label,
    isNew: destinationNode.data.isNew,
    UUID: destinationNode.id
  }

  return destination
}

export default handleModel
